#include<syslog.h>
#include<pthread.h>
#include"thread_channel.h"
#include<proto.h>
#include"server_config.h"
#include<stdlib.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<errno.h>
#include<netinet/in.h>
#include<netinet/ip.h>

struct thread_channel_entity_st
{
    channid_t channid;
    pthread_t tid;
};

thread_channel_entity_st thread_channel[CHANNERNO];
static int tid_next_pos;

void* thr_channel_sndr(void* ptr){
    msg_channel_st * buff;
    media_entity_st*  ent= (media_entity_st*)ptr;

    buff = (msg_channel_st*)malloc(MAX_CHANNEL_MSG); 
    if(buff==NULL){
        syslog(LOG_ERR,"malloc");
        exit(1);
    }
    // int datasize = MAX_DATA;
    buff->channid = ent->channid;
    int len = 0,sendsize=0;
    syslog(LOG_DEBUG,"channid %d try read channel and send [ %s : %d ]",buff->channid,__FILE__,__LINE__);
    while(1){
        len = media_readChannel(ent->channid,buff->data,MAX_DATA); 
        syslog(LOG_DEBUG,"media read channel %d bytes [ %s : %d ]",len,__FILE__,__LINE__);
    // 从指定频道读到buff中方的data，读MAX_DATA大小
        if((sendsize=sendto(server_fd,buff,len+sizeof(channid_t),0,(sockaddr*)&sendaddr,sizeof(sendaddr)))<0){
            syslog(LOG_ERR,"sendto failed");
            exit(1);
        }
        syslog(LOG_DEBUG,"send %d bytes channdl msg in [ %s : %d ]",sendsize,__FILE__,__LINE__);
        sched_yield();

    }
    
    
}


int thread_channel_create(media_entity_st* ptr){
    // tid_next_pos = 0
    int err = pthread_create(&thread_channel[tid_next_pos].tid,NULL,thr_channel_sndr,ptr);
    if(err){
        syslog(LOG_WARNING,"thread");
        return -err;
    }
    thread_channel[tid_next_pos].channid = ptr->channid;
    tid_next_pos++;

    return 0;
}


int thread_channel_destory(media_entity_st* ptr){

    for(int i=0;i<CHANNERNO;i++){
        if(thread_channel[i].channid==ptr->channid){
            if(pthread_cancel(thread_channel[i].tid)<0){
                syslog(LOG_ERR,"thread cancel failed");
                return -ESRCH;
            }
            pthread_join(thread_channel[i].tid,NULL);
            thread_channel[i].channid=-1;
            return 0;
        }
    }
}

int thread_channel_destoryAll(void){
    for(int i=0;i<CHANNERNO;i++){
        if(thread_channel[i].channid>0){
            if(pthread_cancel(thread_channel[i].tid)<0){
                syslog(LOG_ERR,"thread cancel failed");
                return -ESRCH;
            }
            pthread_join(thread_channel[i].tid,NULL);
            thread_channel[i].channid=-1;
        }
    }
    return 0;
}   